/*! @azure/msal-browser v2.38.3 2023-10-27 */
'use strict';
import { __extends, __assign } from '../_virtual/_tslib.js';
import { PerformanceClient } from '@azure/msal-common';
import { BrowserCrypto } from '../crypto/BrowserCrypto.js';
import { GuidGenerator } from '../crypto/GuidGenerator.js';
import { BrowserPerformanceMeasurement } from './BrowserPerformanceMeasurement.js';

/*
 * Copyright (c) Microsoft Corporation. All rights reserved.
 * Licensed under the MIT License.
 */
var BrowserPerformanceClient = /** @class */ (function (_super) {
    __extends(BrowserPerformanceClient, _super);
    function BrowserPerformanceClient(clientId, authority, logger, libraryName, libraryVersion, applicationTelemetry, cryptoOptions) {
        var _this = _super.call(this, clientId, authority, logger, libraryName, libraryVersion, applicationTelemetry) || this;
        _this.browserCrypto = new BrowserCrypto(_this.logger, cryptoOptions);
        _this.guidGenerator = new GuidGenerator(_this.browserCrypto);
        return _this;
    }
    BrowserPerformanceClient.prototype.startPerformanceMeasuremeant = function (measureName, correlationId) {
        return new BrowserPerformanceMeasurement(measureName, correlationId);
    };
    BrowserPerformanceClient.prototype.generateId = function () {
        return this.guidGenerator.generateGuid();
    };
    BrowserPerformanceClient.prototype.getPageVisibility = function () {
        var _a;
        return ((_a = document.visibilityState) === null || _a === void 0 ? void 0 : _a.toString()) || null;
    };
    BrowserPerformanceClient.prototype.deleteIncompleteSubMeasurements = function (inProgressEvent) {
        var rootEvent = this.eventsByCorrelationId.get(inProgressEvent.event.correlationId);
        var isRootEvent = rootEvent && rootEvent.eventId === inProgressEvent.event.eventId;
        var incompleteMeasurements = [];
        if (isRootEvent && (rootEvent === null || rootEvent === void 0 ? void 0 : rootEvent.incompleteSubMeasurements)) {
            rootEvent.incompleteSubMeasurements.forEach(function (subMeasurement) {
                incompleteMeasurements.push(__assign({}, subMeasurement));
            });
        }
        // Clean up remaining marks for incomplete sub-measurements
        if (incompleteMeasurements.length > 0) {
            BrowserPerformanceMeasurement.flushMeasurements(inProgressEvent.event.correlationId, incompleteMeasurements);
        }
    };
    BrowserPerformanceClient.prototype.supportsBrowserPerformanceNow = function () {
        return typeof window !== "undefined" &&
            typeof window.performance !== "undefined" &&
            typeof window.performance.now === "function";
    };
    /**
     * Starts measuring performance for a given operation. Returns a function that should be used to end the measurement.
     * Also captures browser page visibilityState.
     *
     * @param {PerformanceEvents} measureName
     * @param {?string} [correlationId]
     * @returns {((event?: Partial<PerformanceEvent>) => PerformanceEvent| null)}
     */
    BrowserPerformanceClient.prototype.startMeasurement = function (measureName, correlationId) {
        var _this = this;
        // Capture page visibilityState and then invoke start/end measurement
        var startPageVisibility = this.getPageVisibility();
        var inProgressEvent = _super.prototype.startMeasurement.call(this, measureName, correlationId);
        return __assign(__assign({}, inProgressEvent), { endMeasurement: function (event) {
                var res = inProgressEvent.endMeasurement(__assign({ startPageVisibility: startPageVisibility, endPageVisibility: _this.getPageVisibility() }, event));
                _this.deleteIncompleteSubMeasurements(inProgressEvent);
                return res;
            }, discardMeasurement: function () {
                inProgressEvent.discardMeasurement();
                _this.deleteIncompleteSubMeasurements(inProgressEvent);
                inProgressEvent.measurement.flushMeasurement();
            } });
    };
    /**
     * Adds pre-queue time to preQueueTimeByCorrelationId map.
     * @param {PerformanceEvents} eventName
     * @param {?string} correlationId
     * @returns
     */
    BrowserPerformanceClient.prototype.setPreQueueTime = function (eventName, correlationId) {
        if (!this.supportsBrowserPerformanceNow()) {
            this.logger.trace("BrowserPerformanceClient: window performance API not available, unable to set telemetry queue time for " + eventName);
            return;
        }
        if (!correlationId) {
            this.logger.trace("BrowserPerformanceClient: correlationId for " + eventName + " not provided, unable to set telemetry queue time");
            return;
        }
        var preQueueEvent = this.preQueueTimeByCorrelationId.get(correlationId);
        /**
         * Manually complete queue measurement if there is an incomplete pre-queue event.
         * Incomplete pre-queue events are instrumentation bugs that should be fixed.
         */
        if (preQueueEvent) {
            this.logger.trace("BrowserPerformanceClient: Incomplete pre-queue " + preQueueEvent.name + " found", correlationId);
            this.addQueueMeasurement(preQueueEvent.name, correlationId, undefined, true);
        }
        this.preQueueTimeByCorrelationId.set(correlationId, { name: eventName, time: window.performance.now() });
    };
    /**
     * Calculates and adds queue time measurement for given performance event.
     *
     * @param {PerformanceEvents} eventName
     * @param {?string} correlationId
     * @param {?number} queueTime
     * @param {?boolean} manuallyCompleted - indicator for manually completed queue measurements
     * @returns
     */
    BrowserPerformanceClient.prototype.addQueueMeasurement = function (eventName, correlationId, queueTime, manuallyCompleted) {
        if (!this.supportsBrowserPerformanceNow()) {
            this.logger.trace("BrowserPerformanceClient: window performance API not available, unable to add queue measurement for " + eventName);
            return;
        }
        if (!correlationId) {
            this.logger.trace("BrowserPerformanceClient: correlationId for " + eventName + " not provided, unable to add queue measurement");
            return;
        }
        var preQueueTime = _super.prototype.getPreQueueTime.call(this, eventName, correlationId);
        if (!preQueueTime) {
            return;
        }
        var currentTime = window.performance.now();
        var resQueueTime = queueTime || _super.prototype.calculateQueuedTime.call(this, preQueueTime, currentTime);
        return _super.prototype.addQueueMeasurement.call(this, eventName, correlationId, resQueueTime, manuallyCompleted);
    };
    return BrowserPerformanceClient;
}(PerformanceClient));

export { BrowserPerformanceClient };
//# sourceMappingURL=BrowserPerformanceClient.js.map
